﻿Imports System.Net
Imports System.IO
Imports System.Security.Permissions

Public Class ConexionFTP

    Const PRE_FTP As String = "ftp://"

    Private _Server As String = ""
    Private _Port As String = ""
    Private _Credentials As NetworkCredential

    ''' <summary>
    ''' Set the parameters of connection
    ''' </summary>
    ''' <param name="Server"></param>
    ''' <param name="User"></param>
    ''' <param name="Password"></param>
    ''' <param name="Port"></param>
    ''' <remarks></remarks>
    Public Sub New(ByVal Server As String, ByVal User As String, ByVal Password As String, ByVal Port As String)
        Me._Server = Server
        Me._Port = Port
        _Credentials = New NetworkCredential(User, Password)
    End Sub

    ''' <summary>
    ''' Credentials
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function Credentials() As NetworkCredential
        Return _Credentials
    End Function


    ''' <summary>
    ''' This function list the directory passed by parameter
    ''' </summary>
    ''' <param name="directory"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function ListFiles(ByVal directory As String) As List(Of String)
        Dim list As New List(Of String)
        list.Clear() 'if the list isn't empty

        Dim FTP As FtpWebRequest = CType(FtpWebRequest.Create(PRE_FTP & Me._Server & "/" & directory & "/"), FtpWebRequest)

        SetConfigConection(FTP)
        FTP.Method = WebRequestMethods.Ftp.ListDirectory
        Dim read As String = ""
        Try
            Using Response As FtpWebResponse = FTP.GetResponse()
                Using responseStream As Stream = Response.GetResponseStream
                    Using reader = New StreamReader(responseStream)
                        While Not reader.EndOfStream
                            read = reader.ReadLine()
                            list.Add(read)
                        End While
                    End Using
                End Using
            End Using
        Catch ex As Exception
            list.Clear()
            list.Add("?")
        End Try
        Return list
    End Function

    ''' <summary>
    ''' Checks if the path is a directory
    ''' </summary>
    ''' <param name="directory"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function isDirectory(ByVal directory As String) As Boolean
        Dim FTP As FtpWebRequest = CType(FtpWebRequest.Create(PRE_FTP & Me._Server & "/" & directory & "/"), FtpWebRequest)
        SetConfigConection(FTP)
        FTP.Method = WebRequestMethods.Ftp.ListDirectory

        Try
            Using response As FtpWebResponse = DirectCast(FTP.GetResponse(), FtpWebResponse)
                ' Folder exists here
                Return True
            End Using

        Catch ex As WebException
            Dim response As FtpWebResponse = DirectCast(ex.Response, FtpWebResponse)
            'Does not exist
            If response.StatusCode = FtpStatusCode.ActionNotTakenFileUnavailable Then
                Return False
            End If
        End Try
        Return False
    End Function

    ''' <summary>
    ''' Delete a file
    ''' </summary>
    ''' <param name="file"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function DeleteFile(ByVal file As String) As String
        MessageBox.Show("DELETE - " & PRE_FTP & Me._Server & "/" & file)
        Dim FTP As FtpWebRequest = CType(FtpWebRequest.Create(PRE_FTP & Me._Server & "/" & file), FtpWebRequest)

        SetConfigConection(FTP)
        FTP.Method = WebRequestMethods.Ftp.DeleteFile

        Try
            Using respuestaFTP As FtpWebResponse = CType(FTP.GetResponse(), FtpWebResponse)
                respuestaFTP.Close()
            End Using
            Return "El archivo ha sido eliminado"
        Catch ex As Exception
            Return ex.Message
        End Try
    End Function

    ''' <summary>
    ''' Checks if file exist
    ''' </summary>
    ''' <param name="file"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function ExistFile(ByVal file As String) As Boolean

        Dim FTP As FtpWebRequest = CType(FtpWebRequest.Create(PRE_FTP & Me._Server & file), FtpWebRequest)

        ' Fijamos el usuario y la contraseña de la petición
        SetConfigConection(FTP)
        ' Para saber si el objeto existe, solicitamos la fecha de creación del mismo
        FTP.Method = WebRequestMethods.Ftp.GetDateTimestamp

        Try
            ' Si el objeto existe, se devolverá True
            Using respuestaFTP As FtpWebResponse = CType(FTP.GetResponse(), FtpWebResponse)
                respuestaFTP.Close()
            End Using
            Return True
        Catch ex As Exception
            Return False
        End Try
    End Function

    ''' <summary>
    ''' Create a directory
    ''' </summary>
    ''' <param name="directorio"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function CreateDirectory(ByVal directorio As String) As String
        'check if the directory exists
        If ExistFile("/" & directorio) Then
            Return "El directorio ya existe"
        End If

        Dim FTP As FtpWebRequest = CType(FtpWebRequest.Create(PRE_FTP & Me._Server & "/" & directorio), FtpWebRequest)

        SetConfigConection(FTP)
        FTP.Method = WebRequestMethods.Ftp.MakeDirectory

        Try
            Using respuestaFTP As FtpWebResponse = CType(FTP.GetResponse(), FtpWebResponse)
                respuestaFTP.Close()
            End Using
            Return "Directorio creado correctamente"
        Catch ex As Exception
            Return ex.Message
        End Try
    End Function

    ''' <summary>
    ''' Rename a file
    ''' </summary>
    ''' <param name="archivo"></param>
    ''' <param name="archivoNombreNuevo"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function RenameFile(ByVal archivo As String, ByVal archivoNombreNuevo As String) As String

        Dim FTP As FtpWebRequest = CType(FtpWebRequest.Create(PRE_FTP & Me._Server & "/" & archivo), FtpWebRequest)

        SetConfigConection(FTP)
        FTP.Method = WebRequestMethods.Ftp.Rename
        FTP.RenameTo = archivoNombreNuevo

        Try
            Using respuestaFTP As FtpWebResponse = CType(FTP.GetResponse(), FtpWebResponse)
                respuestaFTP.Close()
            End Using
            Return "Renombrado Correctamente"
        Catch ex As Exception
            Return "Error al renombrar"
        End Try
    End Function

    ''' <summary>
    ''' Upload the file
    ''' The params are: 
    ''' path of file in the system, path of file in server, folder of file in server
    ''' Ex, "C:\youpadsfsadf.txt", "/yosadf.txt", "/ruta1/"
    ''' </summary>
    ''' <param name="pathLocalFile"></param>
    ''' <param name="pathRemoteFile"></param>
    ''' <param name="directory"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function UploadFile(ByVal pathLocalFile As String, ByVal pathRemoteFile As String, ByVal directory As String) As String

        Dim infoFichero As New FileInfo(pathLocalFile)

        If Not ExistFile(directory) Then
            CreateDirectory(directory)
        End If

        Dim FTP As FtpWebRequest = CType(FtpWebRequest.Create(PRE_FTP & Me._Server & directory & pathRemoteFile), FtpWebRequest)

        SetConfigConection(FTP)

        FTP.Method = WebRequestMethods.Ftp.UploadFile

        Try
            FTP.ContentLength = infoFichero.Length

            Dim longitudBuffer As Integer
            longitudBuffer = 2048
            Dim lector As Byte() = New Byte(2048) {}

            Dim num As Integer

            Dim fs As FileStream
            fs = infoFichero.OpenRead()


            Dim escritor As Stream
            escritor = FTP.GetRequestStream()
            num = fs.Read(lector, 0, longitudBuffer)

            While (num <> 0)
                escritor.Write(lector, 0, num)
                num = fs.Read(lector, 0, longitudBuffer)
            End While

            'escritor.Close()
            'fs.Close()
            Return "Archivo subido correctamente"
        Catch ex As Exception
            Return ex.Message
        End Try

    End Function

    ''' <summary>
    ''' Download a file
    ''' </summary>
    ''' <param name="localDirectory"></param>
    ''' <param name="remoteFile"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function DownloadFile(ByVal localDirectory As String, ByVal remoteFile As String, ByVal nameOfFile As String) As String

        Dim FTP As FtpWebRequest = CType(FtpWebRequest.Create(PRE_FTP & Me._Server & "/" & remoteFile), FtpWebRequest)

        SetConfigConection(FTP)

        FTP.Method = WebRequestMethods.Ftp.DownloadFile

        Dim buffLength As Integer = 2048
        Dim buff(buffLength) As Byte

        Try
            Using response As System.Net.FtpWebResponse = CType(FTP.GetResponse, System.Net.FtpWebResponse)
                Using responseStream As IO.Stream = response.GetResponseStream
                    Using fs As New IO.FileStream(localDirectory & "\" & nameOfFile, IO.FileMode.Create, FileAccess.ReadWrite, FileShare.None)
                        Dim read As Integer = 0
                        Do
                            read = responseStream.Read(buff, 0, buff.Length)
                            fs.Write(buff, 0, read)
                        Loop Until read = 0
                        responseStream.Close()
                        fs.Flush()
                        fs.Close()
                    End Using
                    responseStream.Close()
                End Using
                response.Close()
            End Using
        Catch ex As Exception
            Return ex.Message
        End Try

        Return "Descarga correcta"

    End Function

    Private Sub SetConfigConection(ByRef FTP As FtpWebRequest)
        FTP.Credentials = Credentials()
        FTP.KeepAlive = False
        FTP.UsePassive = True
        FTP.UseBinary = True
    End Sub

    'por que no aparece el icono de carpeta en las subcarpetas

End Class


